package com.hua.api.modules.express.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.hua.api.core.constants.Status;
import com.hua.api.core.framework.config.scurity.UserInfo;
import com.hua.api.core.framework.util.exception.ApiError;
import com.hua.api.core.util.StringUtil;
import com.hua.api.core.util.ValidationUtil;
import com.hua.api.modules.express.dao.ExpressOrderDao;
import com.hua.api.modules.express.dao.ShopInfoExpressDao;
import com.hua.api.modules.express.domain.ExpressOrder;
import com.hua.api.modules.express.domain.ShopInfoExpress;
import com.hua.api.modules.express.repository.ShopInfoExpressRepository;
import com.hua.api.modules.express.service.ExpressInfoService;
import com.hua.api.modules.express.service.ShopInfoExpressService;
import com.hua.api.modules.express.service.dto.ExpressInfoCriteria;
import com.hua.api.modules.finance.dao.UserAccountDao;
import com.hua.api.modules.finance.domain.UserAccount;
import com.hua.api.modules.finance.service.UserAccountService;
import com.hua.api.modules.order.dao.OrderInfoDao;
import com.hua.api.modules.order.domain.OrderInfo;
import com.hua.api.modules.order.service.OrderInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class ShopInfoExpressServiceImpl implements ShopInfoExpressService {

    public final ExpressInfoServiceFactory expressInfoServiceFactory;

    public final ShopInfoExpressRepository shopInfoExpressRepository;

    public final ShopInfoExpressDao shopInfoExpressDao;

    public final OrderInfoDao orderInfoDao;

    public final UserAccountDao userAccountDao;

    public final ExpressOrderDao expressOrderDao;

    public final UserAccountService userAccountService;

    public final OrderInfoService orderInfoService;

    @Override
    public JSONObject queryAllStore(ExpressInfoCriteria criteria,String expressCode) {
        ExpressInfoService expressInfoService = expressInfoServiceFactory.getExpressInfoService(expressCode);
        ValidationUtil.requireNotNull(expressInfoService,"找不到 ExpressInfoService expressCode="+expressCode);
        return expressInfoService.queryAllStores(criteria);
    }

    /**
     * 店铺绑定
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public JSONObject bindShopInfoExpress(Integer shopId, String expressCode,String storeId) {
        ExpressInfoService expressInfoService = expressInfoServiceFactory.getExpressInfoService(expressCode);
        ValidationUtil.requireNotNull(expressInfoService,"找不到 ExpressInfoService expressCode="+expressCode);

        if(!StringUtil.isEmpty(storeId)){
            // System.out.println(" expressInfoService.storeOpertionSync storeId="+storeId);
            // 提供了 storeId 则同步三方店铺信息到本地
            JSONObject data = expressInfoService.storeOpertionSync(storeId,expressCode,shopId);
            return data;
        }else{
            ShopInfoExpress shopInfoExpress = shopInfoExpressRepository.findByShopIdAndExpressCode(shopId, expressCode);
            if(shopInfoExpress == null){
                expressInfoService.storeOperationAdd(shopId,expressCode);
            }else {
                expressInfoService.storeOperationModify(shopId,expressCode,shopInfoExpress.getStoreId());
            }
            return new JSONObject();
        }



    }

    @Override
    public  List<ShopInfoExpress> shopInfoExpressList(Integer orderId) {
        return shopInfoExpressDao.queryShopInfoExpress(orderId);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public ExpressOrder orderCalculate(Integer orderId,  Integer expressId,Integer isSaleAfter) {
        log.info("生成物流单计算价格计算 orderId={}, expressId={}",orderId,expressId);
        OrderInfo orderInfo = orderInfoDao.getObject(OrderInfo.class,orderId);
        ValidationUtil.requireNotNull(orderInfo,"订单数据不存在");

        Status.LogisticsStatus status = Status.LogisticsStatus.fromValue(orderInfo.getLogisticsStatus());
        if(status!=Status.LogisticsStatus.daipeisong && status!=Status.LogisticsStatus.yiquxiao){
            throw ApiError.Type.LOGIC_ERROR.toException("订单配送状态异常，无法安排配送");
        }

        ShopInfoExpress express = orderInfoDao.getObject(ShopInfoExpress.class,expressId);
        ValidationUtil.requireNotNull(express,"配送渠道不存在 expressId="+expressId);
        if(!StringUtil.equals(orderInfo.getShopId(),express.getShopId())){
            throw ApiError.Type.LOGIC_ERROR.toException("订单店铺id与店铺物流的店铺id不一致！");
        }

        UserAccount account = userAccountDao.findUserAccountUseShopId(orderInfo.getShopId());
        ValidationUtil.requireNotNull(account,"账户信息不存在 shopId="+orderInfo.getShopId());

        ExpressInfoService expressInfoService = expressInfoServiceFactory.getExpressInfoService(express.getExpressCode());
        ValidationUtil.requireNotNull(expressInfoService,"expressInfoService 异常 expressCode="+express.getExpressCode());
        ExpressOrder expressOrder = expressInfoService.orderCalculate(express,orderInfo,account,isSaleAfter);

        expressOrderDao.saveObject(expressOrder);
        return expressOrder;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public JSONObject orderPlace(String expressOrderNo) {
        ExpressOrder eorder = expressOrderDao.findByExpressOrderNo(expressOrderNo);
        ValidationUtil.requireNotNull(eorder,"物流单信息不存在！expressOrderNo="+expressOrderNo);
        ExpressInfoService expressInfoService = expressInfoServiceFactory.getExpressInfoService(eorder.getExpressCode());
        OrderInfo orderInfo = orderInfoDao.getObject(OrderInfo.class,eorder.getOrderId());
        // 非售后的订单配送，则需要判断订单状态为待配送或者取消后重新配送。
        if(StringUtil.equals(Status.LOGIC_N,eorder.getIsSaleAfter())){
            // 非售后单则判断订单配送状态
            Status.LogisticsStatus logisticsStatus = Status.LogisticsStatus.fromValue(orderInfo.getLogisticsStatus());
            if(logisticsStatus!= Status.LogisticsStatus.daipeisong && logisticsStatus!=Status.LogisticsStatus.yiquxiao){
                throw ApiError.Type.LOGIC_ERROR.toException("订单状态异常，非待配送状态");
            }
        }
        if(null!=expressInfoService){
            // 更新实际的扣除金额
            eorder = expressInfoService.orderPlace(eorder);
            eorder.setOrderStatus(Status.LogisticsStatus.daijiedan.getValue());
            eorder.setOrderTime(new Date());
            expressOrderDao.updateObject(eorder);
            if(null!=orderInfo){
                if(!StringUtil.equals(Status.LOGIC_TRUE,eorder.getIsSaleAfter())){
                    // 非售后单则同步订单配送状态
                    orderInfoService.onOrderInfoSendPaidan(orderInfo.getOrderNo(),eorder.getId());
                }
                Double realMoney = eorder.getRealFee()/100d;
                // 快递费从账户扣款
                userAccountService.onUserAccountSubUseShopId(orderInfo.getShopId(),realMoney,"express_order","物流下单扣费费用，单号:"+eorder.getExpressOrderNo());
            }
        }else {
            throw ApiError.Type.LOGIC_ERROR.toException("expressInfoService is null!");
        }
        return new JSONObject();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public JSONObject addition(ExpressInfoCriteria criteria, UserInfo user) {
        ValidationUtil.requireNotNull(criteria.getAmount(),"请输入加价金额!");
        ValidationUtil.requireNotNull(criteria.getExpressOrderNo(),"请输入物流单号!");
        ExpressOrder eorder = expressOrderDao.findByExpressOrderNo(criteria.getExpressOrderNo());
        ValidationUtil.requireNotNull(eorder,"物流单信息不存在！expressOrderNo="+criteria.getExpressOrderNo());
        OrderInfo orderInfo = orderInfoDao.getObject(OrderInfo.class,eorder.getOrderId());
        ExpressInfoService expressInfoService = expressInfoServiceFactory.getExpressInfoService(eorder.getExpressCode());
        if(null!=expressInfoService){
            Integer fenMoney = criteria.getAmount().intValue()*100;
            expressInfoService.addition(eorder,fenMoney);
            Integer addFee = eorder.getAddFee()==null?0:eorder.getAddFee();
            eorder.setAddFee(addFee+fenMoney);
            eorder.setRealFee(eorder.getRealFee()+fenMoney);
            expressOrderDao.updateObject(eorder);
            if(null!=orderInfo){
                // 快递费从账户扣款
                userAccountService.onUserAccountSubUseShopId(orderInfo.getShopId(),criteria.getAmount(),"express_order","物流单加价扣费费用，单号:"+eorder.getExpressOrderNo());
            }
        }
        return new JSONObject();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void abortOrder(ExpressInfoCriteria criteria) {
        log.info("ShopInfoExpressServiceImpl.abortOrder() expressOrderNo={}",criteria.getExpressOrderNo());
        ValidationUtil.requireNotNull(criteria.getExpressOrderNo(),"请输入物流单号!");
        ExpressOrder eorder = expressOrderDao.findByExpressOrderNo(criteria.getExpressOrderNo());
        ValidationUtil.requireNotNull(eorder,"物流单信息不存在！expressOrderNo="+criteria.getExpressOrderNo());
        OrderInfo orderInfo = orderInfoDao.getObject(OrderInfo.class,eorder.getOrderId());
        ExpressInfoService expressInfoService = expressInfoServiceFactory.getExpressInfoService(eorder.getExpressCode());
        if(null!=expressInfoService){
            JSONObject data = expressInfoService.abortOrder(criteria);
            log.info("ShopInfoExpressServiceImpl.abortOrder() data={}",data.toString());

            Integer punishAmount = 0; // 取消订单产生的费用
            Integer backFee = 0; //返回的费用
            // 返回金额
            if(data.containsKey("sendBackFee")){
                backFee = data.getInteger("sendBackFee");
            }
            // 扣除金额
            if(data.containsKey("deductAmount")){
                punishAmount = data.getInteger("deductAmount");
            }
            eorder.setPunishAmount(punishAmount);
            eorder.setOrderStatus(Status.LogisticsStatus.yiquxiao.getValue());
            expressOrderDao.updateObject(eorder);

            if(null!=orderInfo){
                // 非售后单则需要同步订单的配送状态
                if(!StringUtil.equals(eorder.getIsSaleAfter(),Status.LOGIC_Y)){
                    log.info("配送取消，订单状态修改为取消状态 orderInfoService.onOrderInfoSendQuxiao({});",orderInfo.getOrderNo());
                    orderInfoService.onOrderInfoSendQuxiao(orderInfo.getOrderNo());
                }

                // 退款移到消息通知处执行
//                Double backYuan = backFee/100d;
//                log.info("ShopInfoExpressServiceImpl.abortOrder() 取消物流订单，返回金额 expressOrderNo={},backYuan={}",criteria.getExpressOrderNo(),backYuan);
//                if(backYuan>0){
//                    userAccountService.onUserAccountAddUseShopId(orderInfo.getShopId(),backYuan,"express_order","取消物流返回费用，单号:"+eorder.getExpressOrderNo());
//                }

            }
        }
    }

    @Override
    public JSONObject courierInfo(ExpressInfoCriteria criteria) {
        log.info("ShopInfoExpressServiceImpl.abortOrder() expressOrderNo={}",criteria.getExpressOrderNo());
        return null;
    }

    @Override
    public JSONObject getUserAccount(String expressCode) {
        ExpressInfoService expressInfoService = expressInfoServiceFactory.getExpressInfoService(expressCode);
        if(null!=expressInfoService){
             return expressInfoService.getUserAccount();
        }
        return new JSONObject();
    }


}